package org.performancetracker.simple;

import org.performancetracker.api.Tracker;
import org.performancetracker.api.Aggregator;
import org.performancetracker.api.Reporter;

/**
 * Basic tracker mock implementation.
 *
 * 
 *
 * @author: jaronschut
 */

public class TrackerImpl implements Tracker, Reporter {

	private final static String EXCEPTION_ALREADY_STOPPED = "IllegalState: Tracker has already been stopped";
	private final static String EXCEPTION_ALREADY_STARTED = "IllegalState: Tracker has already been started";
	private final static String EXCEPTION_NOT_STARTED = "IllegalState: Tracker has not been started";
	private final static String EXCEPTION_NOT_STOPPED = "IllegalState: Tracker has not been stopped";
	private final static String EXCEPTION_REVERSE = "IllegalState: Tracker has not been started but already has been stopped";

    /* The tracker aggregator set during construction */
    private final Aggregator aggregator;

    /* The start time of the tracker set during construction */
    private Long startTime;

    /* Message set when the tracker */
    private String message;

	/* The endtime */
    private Long endTime;

    /**
     * Protected constructor.
     *
     * @param aggregator
     */
    public TrackerImpl(Aggregator aggregator) {
        this.aggregator = aggregator;
    }

	/*********** TRACKER INTERFACE **************/
	/**
	 * Aggregate the tracker.
	 *
	 * typical calling is:
	 *
	 * tracker.stop().aggregate("all ok");
	 */
    public void aggregate(String message) {
		if (startTime != null && endTime != null) {
			this.message = message;
			this.aggregator.aggregate(this);
		} else {

			throw new IllegalStateException(EXCEPTION_NOT_STOPPED);
		}
    }

    /**
     * Start the timer.
     *
     * @return itself
     */
	public Tracker start() {
		if (startTime == null) {

			if (endTime == null) {

				startTime = System.currentTimeMillis();

			} else {

				throw new IllegalStateException(EXCEPTION_REVERSE);
			}
		} else {

			throw new IllegalStateException(EXCEPTION_ALREADY_STARTED);
		}
		return this;
	}

	public Tracker stop() {
		if (startTime == null) {

			throw new IllegalStateException(EXCEPTION_NOT_STARTED);

		} else {

			if (endTime == null) {

				endTime = System.currentTimeMillis();

			} else {

				throw new IllegalStateException(EXCEPTION_ALREADY_STOPPED);
			}
		}
		return this;
	}

	/*********** REPORTER INTERFACE **************/
    /**
     * Retrieve the message.
     *
     * @return
     */
    public String getMessage() {
        return message;
    }

    /**
     * Retrieve the starttime.
     *
     * @return
     */
    public Long getStartTime() {
        return startTime;
    }

    /**
     * Retrieve the starttime.
     *
     * @return
     */
    public Long getEndTime() {
        return endTime;
    }

    /**
     * Retrieve the elapsed time.
     *
     * @return
     */
    public Long getElapsedTime() {
        return endTime - startTime;
    }
}